package com.woniu.inlet.listen;

import com.rabbitmq.client.Channel;
import com.woniu.outlet.client.OrderMessage;
import com.woniu.outlet.mysql.ReceivedMsgUserRegisterDao;
import com.woniu.outlet.mysql.po.ReceivedMsgUserRegisterMySQL;
import com.woniu.service.UserDetailService;
import com.woniu.service.domain.UserDetail;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;

/**
 * 用户注册通知支付模块
 */
@Slf4j
@Component
@RabbitListener(queues = "user_register_pay")
public class UserRegisterListener {

    @Autowired
    private ReceivedMsgUserRegisterDao receivedMsgUserRegisterDao;
    @Autowired
    private UserDetailService userDetailService;
    @Autowired
    private OrderMessage orderMessage;

    @Transactional // 抛出异常，事务回滚。
    @RabbitHandler
    public void handle(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
        String[] strings = message.split("!");
        if (strings.length < 2) {
            channel.basicReject(tag, false);
            throw new RuntimeException("接收到的消息内容格式错误");
        }

        // 消息的第一部分是：消息在【可靠消息服务】那边的消息表中的ID（唯一）。
        String messageIdString = strings[0];
        Integer messageId = Integer.parseInt(messageIdString);

        // 消息的第二部分是：订单模块发送过来的具体消息 。
        String substring = strings[1];

        try {
            // 1. 判断是否是重复消息：insert into 去重表
            receivedMsgUserRegisterDao.insert(new ReceivedMsgUserRegisterMySQL(null, messageId));
        } catch (RuntimeException e) {
            log.debug("该消息重复");
            // 2. 拒绝消息。要求 RabbitMQ 从队列中删除。
            channel.basicReject(tag, false);
            return;
        }

        try {
            // 执行本地业务逻辑
            log.debug("执行本地业务逻辑");
            Integer userId = Integer.valueOf(substring);
            UserDetail userDetail = new UserDetail();
            log.debug("新用户的id为：{}",userId);
            userDetail.setUserId(userId);
            userDetail.setPayCount(5);
            userDetail.setRestAmount(new BigDecimal(0));
            userDetail.setTotalAmount(new BigDecimal(0));
            userDetailService.addUser(userDetail);

            // 确认接收，并处理该消息：
            channel.basicAck(tag, false);
            // 发起 HTTP 请求: http://可靠消息服务/message/{}/received"
            orderMessage.receivedMessage(messageId);
        }catch (RuntimeException e){
            // 执行本地业务出错，拒绝消息，要求 RabbitMQ 从队列中删除。
            // 等待发送者的定时器下次再发送一次。
            channel.basicReject(tag, false);
            throw new NullPointerException();
        }
    }
}
